package de.fhffm.gaertnerei.gui;
/**
 * @author Michael Wyrzykowski & Julian Schmücker
 */

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.text.MaskFormatter;

import de.fhffm.gaertnerei.exceptions.EingabeException;
import de.fhffm.gaertnerei.tabellen.Aussaat;
import de.fhffm.gaertnerei.tabellen.Ernte;

public class ErnteFenster implements ActionListener {
	
	private double ertragDouble;
	
	private String datumString;
	private String genaueReifezeitString;
	private String aussaatDatumString;
	private String stueckzahlString;
	private String ertragString;
	
	private int stueckzahlInt;
	
	private JTextField textfeldErtrag = new JTextField(8);
	private JTextField textfeldStueckzahl = new JTextField(8);
	
	private JFormattedTextField textfeldDatum ;
	
	private JLabel labelErtrag = new JLabel(" Ertrag (gramm) :");
	private JLabel labelStueckzahl = new JLabel(" Stückzahl :");
	private JLabel labelDatum = new JLabel(" Datum :");
	private JLabel labelInfo = new JLabel();
	
	private JButton buttonSpeichern = new JButton("Speichern");
	private JButton buttonAbbrechen = new JButton("Abbrechen");
	
	private JPanel panelEingabe = new JPanel(new GridLayout(4,2));
	private JPanel panelButton = new JPanel();
	private JPanel panelInfo = new JPanel();

	private JFrame ernteFrame = new JFrame();
	
	private List<String> ausgewaehlteZeile;
	
	private StringBuilder stringBuilder = new StringBuilder();
	
	private MaskFormatter datumFormat= null;
	
	private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd.MM.yyyy");
	
	private Date aktuellesDatum = new Date();
	private Date aussaatDatum = null;;
	private Date ernteDate = null;
	
	
	public ErnteFenster(List<String> ausgewaehlteZeile){
		
		this.ausgewaehlteZeile = ausgewaehlteZeile;
		
		erstelleFenster();
		setzeInfo();
		setzeEingaben();
		setzeButton();
		setzePanel();
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		
		Object obj = e.getSource();
		
		if (obj == buttonAbbrechen) {	
			ernteFrame.dispose();
		}
		
		/*
		 * Nachdem der Button Speichern gedrückt wurde, wird die Eingabe auf ihre richtigkeit überprüft
		 * tritt hier kein Fehler auf dan wird überprüft ob das eingegebene Datum die vorraussetzungen 
		 * (nicht nach dem Ernte datum, Aussaat datum ungleich Ernte Datum)
		 * erfüllt, denn wenn das Datum die vorraussetzung erfüllt dan lässt sich aus diesem
		 * die genaue Reifezeit berrechnen!
		 * 
		 * Danach wird die Ernte eingefügt und eine bestätigung ausgegeben!
		 */
		
			if(obj == buttonSpeichern){

				if(ueberpruefeEingabe()) {
					
					if(istBerechnungMoeglich()){
						
						berechneGenaueReifezeit();
						fuegeErnteEin();
						einfügenEnde();
						
					}else{
						
						System.out.println("Fehler bei der Berechnung!");
					}

				}else{
					System.out.println("Fehler bei der Eingabe");
				}	
			}
	}

	private void erstelleFenster() {

		ernteFrame.setSize(400,500);
		ernteFrame.setLocationRelativeTo(null);
		ernteFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		ernteFrame.setVisible(true);
		ernteFrame.setResizable(false);
		ernteFrame.setLayout(new BorderLayout());
		ernteFrame.setTitle("Aussaat Ernten");		
	}

	private void setzeInfo() {

		stringBuilder.append("<html>Die Pflanze: '").append(ausgewaehlteZeile.get(2)).append("'");
		stringBuilder.append("<br>").append("Aus der Aussaat mit der ID: ").append(ausgewaehlteZeile.get(0)).append(" ernten.<br><br>");
		
		labelInfo.setText(stringBuilder.toString());
		panelInfo.add(labelInfo);
		stringBuilder.setLength(0);				
	}

	private void setzeEingaben() {

		panelEingabe.add(labelErtrag);
		panelEingabe.add(textfeldErtrag);
		textfeldErtrag.setToolTipText("Ertrag der Ernte in gramm");
		panelEingabe.add(labelStueckzahl);
		panelEingabe.add(textfeldStueckzahl);
		textfeldStueckzahl.setToolTipText("Anzahl der geernteten Pflanzen");
		panelEingabe.add(labelDatum);
		setzeDatumAlsText();		
	}

	private void setzeButton() {

		panelButton.add(buttonSpeichern);
		panelButton.add(buttonAbbrechen);
		buttonSpeichern.addActionListener(this);
		buttonAbbrechen.addActionListener(this);		
	}

	private void setzePanel() {

		ernteFrame.getContentPane().add(panelInfo, BorderLayout.NORTH);
		ernteFrame.getContentPane().add(panelEingabe,BorderLayout.CENTER);
		ernteFrame.getContentPane().add(panelButton,BorderLayout.SOUTH);
		ernteFrame.pack();		
	}

	private void setzeDatumAlsText() {
		
		try {
			datumFormat = new MaskFormatter("##.##.####");
		} catch (ParseException e) {
			e.printStackTrace();
		}
		
		textfeldDatum = new JFormattedTextField(datumFormat);
		textfeldDatum.setText(simpleDateFormat.format(aktuellesDatum));
		panelEingabe.add(textfeldDatum);
	}

	private boolean ueberpruefeEingabe() {
		
		boolean pruefe = false;
		try {
			ueberpruefeDatum();
			pruefe = hohleEingabe();

		} catch (EingabeException e) {
			System.out.println("Eingabe Fehler");
		} catch (NumberFormatException n){
			System.out.println("Bitte Zahlen eingeben!");
			JOptionPane.showMessageDialog(null,"Bitte für den Ertrag und die Stückzahl Zahlen eingeben.","Fehler",JOptionPane.ERROR_MESSAGE);
		}
		return pruefe;
	}

	private boolean hohleEingabe() throws EingabeException {
		
		ertragDouble = Double.parseDouble(textfeldErtrag.getText());
		stringBuilder.append(ertragDouble).append(" gramm");
		ertragString = stringBuilder.toString();
		stringBuilder.setLength(0);
		stueckzahlInt = Integer.parseInt(textfeldStueckzahl.getText());
		stringBuilder.append(stueckzahlInt).append(" Stück");
		stueckzahlString = stringBuilder.toString();
		stringBuilder.setLength(0);
		
		if(isEingabeLeer()){
			
			throw new EingabeException("Eine oder mehrere Eingaben fehlen, bitte keine Negativen Zahlen angeben!");	
		
		}else{

			return true;
		}
	}

	private boolean isEingabeLeer() {
		
		if(ertragDouble <= 0.0 || stueckzahlInt <= 0 ){
			
			return true;
		
		}else{
		
			return false;
		}
	}

	private void ueberpruefeDatum() throws EingabeException {
		
		/*Das Aktuelle Datum wird in einen String mit dem format dd.mm.yyyy umgewandelt.
		Dan wird das aktuelle Datum wieder als Date gespeichert nur mit dem vorher definierten format
		so kann das aktuelle Datum mit dem eingegebenen Datum verglichen werden */
		
		datumString = textfeldDatum.getText();				
		String aktuellesDatumString = simpleDateFormat.format(aktuellesDatum);
		String[] teilString = datumString.split(Pattern.quote(".")); // Das eingegebene Datum wird gesplittet
		 
		try {
			 ernteDate = simpleDateFormat.parse(datumString);
			 aktuellesDatum = simpleDateFormat.parse(aktuellesDatumString);
			
		} catch (ParseException e) {
			e.printStackTrace();
		}
		
		if(ernteDate.after(aktuellesDatum)){
			throw new EingabeException("Das eingegebene Datum darf nicht nach dem aktuellem Datum liegen!");
			
		// Eingegebenes Datum ist ungültig wenn kein Tag, Monat oder Jahr angegeben wird bsp.: 00.00.0000	
		// um dies zu überprüfen wird der vorher gesplittete String genutzt
		}else if((teilString[0]).equals("00") || (teilString[1].equals("00") || teilString[2].equals("0000") || teilString[2].substring(0, 1).equals("0")) ){
		    throw new EingabeException("Das Datum muss im format tt.mm.yyyy eingegeben werden und darf nicht 0 sein");
		
		}else if(ernteDate.equals(aktuellesDatum)){
			System.out.println("Alles ok");
		}
		
	}
	
	private void fuegeErnteEin() {
		
		int aussaatID = Integer.parseInt(ausgewaehlteZeile.get(0));
		String pflanze = ausgewaehlteZeile.get(2);
		
		EntityManagerFactory factory;
		factory = Persistence.createEntityManagerFactory("chilidatenbank");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
		
		Query q = em.createQuery("SELECT a FROM Aussaat a WHERE a.aussaatID =:ID");
				  q.setParameter("ID", aussaatID);
		
		Aussaat aussaat = (Aussaat) q.getSingleResult();
		
		Ernte ernte = new Ernte();
		ernte.setGeerntetepflanze(pflanze);
		ernte.setErtrag(ertragString);
		ernte.setStueckzahl(stueckzahlString);
		ernte.setErnteDatum(datumString);
		ernte.setGenaueReifezeit(genaueReifezeitString);
		ernte.setAussaat(aussaat);
		
		aussaat.getErnte().add(ernte);
		
		em.persist(ernte);
		em.persist(aussaat);
		em.getTransaction().commit();
		em.close();	
	}

	private boolean istBerechnungMoeglich()  {
		
		hohleAussaatDatum();
		
		try {
			
			aussaatDatum = simpleDateFormat.parse(aussaatDatumString);
			ernteDate = simpleDateFormat.parse(datumString);
			
		} catch (ParseException e) {
			e.printStackTrace();
			return false;
		}
		
		try {
			
			if(aussaatDatum.equals(ernteDate)){
				
				throw new EingabeException("Das Ernte Datum darf nicht gleich dem Datum der Aussaat sein!");
			
			}else if(ernteDate.before(aussaatDatum)){
				
				throw new EingabeException("Das Ernte Datum darf nicht vor dem Aussaat Datum liegen!");
			
			}
			
		}catch(EingabeException e){
			
			return false;
		}
		
		return true;
	}

	private void berechneGenaueReifezeit(){ 
		
			long vergangeneMiliSek = ernteDate.getTime() - aussaatDatum.getTime();
			
			/*
			 * Milisekunden / 1000 => Sekunden
			 * Sekunden / 60 => Minuten
			 * Minuten / 60 => Stunden
			 * Stunden / 24 => Tage
			 */
			
			int vergangeneTage = (int) (vergangeneMiliSek/(1000*60*60*24));
			stringBuilder.append(vergangeneTage).append(" Tag/e");
			genaueReifezeitString = stringBuilder.toString();
			
		}

	private void hohleAussaatDatum() {
		
		int aussaatID = Integer.parseInt(ausgewaehlteZeile.get(0));

		EntityManagerFactory factory;
		factory = Persistence.createEntityManagerFactory("chilidatenbank");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
		
		Query q = em.createQuery("SELECT a FROM Aussaat a WHERE a.aussaatID =:ID");
				  q.setParameter("ID",aussaatID);
		Aussaat aussaat = (Aussaat) q.getSingleResult();	
		
		aussaatDatumString = aussaat.getAussaatDatum();
		
		em.close();
		
	}

	private void einfügenEnde() {
		
		Object[] options = {"Fertig!","Neue Ernte!"};
		int selected = JOptionPane.showOptionDialog(null,"Ernte hinzugefügt!", "Ernten Erfolgreich", JOptionPane.YES_NO_OPTION,
					   JOptionPane.QUESTION_MESSAGE, null , options ,options[1]);
		
		switch(selected){
		case 0:
			ernteFrame.dispose();
			break;
		case 1:
			ernteFrame.dispose();
			new FortschrittTabellenFenster(3);
			break;
		}
	}

}